/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controle;

import Entidades.No;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author adriano
 */
public class Rota {

    private ArrayList<No> rota = new ArrayList<No>();    
    private float fitness;

    public Rota() {
        rota = new ArrayList();
        fitness = 0;
    }
    
    public Rota(ArrayList<No> nos) {
        rota = nos;
        fitness = 0;
    }

    public ArrayList<No> getRota() {
        return rota;
    }

    public void setRota(ArrayList<No> rota) {
        this.rota = rota;
    }

    public float getFitness() {
        return fitness;
    }

    public String getFitnessString() {
        String retorno = "0";
        DecimalFormat formatter = new DecimalFormat("#.00");
        try {
            retorno = formatter.format(fitness);
        } catch (Exception ex) {
            System.err.println("Erro ao formatar numero: " + ex);
        }
        return retorno;
    }

    public void setFitness(float fitness) {
        this.fitness = fitness;
    }

//    public void geraCidades(int tamanho) {
//        rota.clear();
//        for (int i = 0; i < tamanho; i++) {
//            No nodo = new No(i, i, 400);
//            rota.add(nodo);
////            System.out.println("Elemento:" + nodo.getId() + " posicao:" + nodo.getPos() + "(" + nodo.getX() + ", " + nodo.getY() + ")");
//        }
//        calculaFitness();
//    }

    public Rota cruzar(Rota rotaAux) {
        int tamanho = rota.size();        
        Random r = new Random();
        int x = r.nextInt(tamanho);
        int y = r.nextInt(x);
            
        Rota rotaA = new Rota();
        Rota rotaB = new Rota();
        rotaA.setRota(rota);        
        rotaB.setRota(rotaAux.getRota());
                
        this.calculaFitness();
        rotaAux.calculaFitness();
        return rotaAux;
    }

    /**
     * Gera duas psições aleatórias para trocar a posição.
     */
    public void mutar() {
        int pos = rota.size();
        Random r = new Random();
        int i = r.nextInt(pos);
        int j = r.nextInt(pos);
        No aux = rota.get(i);
        rota.set(i, rota.get(j));
        rota.set(j, aux);
    }

    /**
     * Calcula o fittnes da rota e salva na variavel.
     */
    public void calculaFitness() {
        float valor = 0;
        int j = rota.size() - 1;
        float parcial;
        for (int i = 0; i < j; i++) {
            parcial = calculaHipotenusa(i, i + 1);
            valor = valor + parcial;
//            System.out.println("Fitness " + i + " = " + parcial);
        }
        parcial = calculaHipotenusa(0, j);
        valor = valor + parcial;
//        System.out.println("Fitness " + j + " = " + parcial + " TOTAL = " + valor);
        setFitness(valor);
    }

    private float calculaHipotenusa(int i, int j) {
        float a = (rota.get(i).getCoordenadaX() - rota.get(j).getCoordenadaX());
        float b = (rota.get(i).getCoordenadaY() - rota.get(j).getCoordenadaY());
        double retorno = Math.sqrt((Math.pow(a, 2) + Math.pow(b, 2)));
        return (float) retorno;
    }

    public Rota embaralha() {
        int pos = rota.size();
        Random r;
        for (int i = 0; i < pos; i++) {
            r = new Random();
            int j = r.nextInt(pos);
            No aux = rota.get(i);
            rota.set(i, rota.get(j));
            rota.set(j, aux);
        }
        Rota aux = new Rota();
        aux.setRota(rota);
        aux.calculaFitness();
        return aux;
    }

    /**
     * 
     */
    private void trocaPosicao() {
        int pos = rota.size();
        Random r = new Random();
        int i = r.nextInt(pos);
        int j = r.nextInt(pos);
        No aux = rota.get(i);
        rota.set(i, rota.get(j));
        rota.set(j, aux);
    }
}
